Add 'live' parameter to migrate.
{'op' : 'save',
'file' : filename })
- def xend_domain_migrate(self, id, dst):
+ def xend_domain_migrate(self, id, dst, live=0):
return self.xendPost(self.domainurl(id),
- {'op' : 'migrate',
- 'destination': dst })
+ {'op' : 'migrate',
+ 'destination': dst,
+ 'live' : live })
def xend_domain_pincpu(self, id, cpu):
return self.xendPost(self.domainurl(id),
self.refresh_schedule()
return val
- def domain_migrate(self, id, dst):
+ def domain_migrate(self, id, dst, live):
"""Start domain migration.
@param id: domain id
print 'domain_migrate>', id, dst
dominfo = self.domain_lookup(id)
xmigrate = XendMigrate.instance()
- val = xmigrate.migrate_begin(dominfo.id, dst)
+ val = xmigrate.migrate_begin(dominfo.id, dst, live=live)
print 'domain_migrate<', val
return val
"""Representation of a migrate in-progress and its interaction with xfrd.
"""
- def __init__(self, xid, dom, host, port):
+ def __init__(self, xid, dom, host, port, live):
XfrdInfo.__init__(self)
self.xid = xid
self.state = 'begin'
self.dst_host = host
self.dst_port = port
self.dst_dom = None
+ self.live = live
self.start = 0
def sxpr(self):
- sxpr = ['migrate', ['id', self.xid], ['state', self.state] ]
+ sxpr = ['migrate',
+ ['id', self.xid ],
+ ['state', self.state ],
+ ['live', self.live ] ]
sxpr_src = ['src', ['host', self.src_host], ['domain', self.src_dom] ]
sxpr.append(sxpr_src)
sxpr_dst = ['dst', ['host', self.dst_host] ]
self.src_dom,
vmconfig,
self.dst_host,
- self.dst_port])
+ self.dst_port,
+ self.live ])
def xfr_migrate_ok(self, xfrd, val):
dom = int(sxp.child0(val))
reactor.connectTCP('localhost', XFRD_PORT, xcf)
return info
- def migrate_begin(self, dom, host, port=XFRD_PORT):
+ def migrate_begin(self, dom, host, port=XFRD_PORT, live=0):
"""Begin to migrate a domain to another host.
@param dom: domain
# Check dom for existence, not migrating already.
# Subscribe to migrate notifications (for updating).
xid = self.nextid()
- info = XendMigrateInfo(xid, dom, host, port)
+ info = XendMigrateInfo(xid, dom, host, port, live)
self.session_begin(info)
return info.deferred
def op_migrate(self, op, req):
fn = FormFn(self.xd.domain_migrate,
[['dom', 'str'],
- ['destination', 'str']])
+ ['destination', 'str'],
+ ['live', 'int']])
deferred = fn(req.args, {'dom': self.dom.id})
print 'op_migrate>', deferred
deferred.addCallback(self._op_migrate_cb, req)
req.write('<form method="post" action="%s">' % url)
req.write('<br><input type="submit" name="op" value="migrate">')
req.write(' To host: <input type="text" name="destination">')
+ req.write('<input type="checkbox" name="live" value="1">Live')
req.write('</form>')
fn=set_true, default=0,
use="Print this help.")
+gopts.opt('live', short='l',
+ fn=set_true, default=0,
+ use="Use live migration.")
+
def help(argv):
gopts.argv = argv
gopts.usage()
dst = args[1]
if dom in [DOM0_NAME, DOM0_ID]:
opts.err('Cannot migrate ' + dom)
- server.xend_domain_migrate(dom, dst)
+ server.xend_domain_migrate(dom, dst, opts.vals.live)
* At some point during this the domain is suspended, and then there's no way back.
* Even if something later goes wrong we can't restart the domain.
*/
-int xen_domain_snd(Conn *xend, IOStream *io, uint32_t dom, char *vmconfig, int vmconfig_n){
+int xen_domain_snd(Conn *xend, IOStream *io,
+ uint32_t dom,
+ char *vmconfig, int vmconfig_n,
+ int live){
int err = 0;
#ifdef _XEN_XFR_STUB_
char buf[1024];
ioctxt->suspend = domain_suspend;
ioctxt->vmconfig = vmconfig;
ioctxt->vmconfig_n = vmconfig_n;
-
+ if(live){
+ ioctxt->flags |= XCFLAGS_LIVE;
+ }
err = xc_linux_save(xcinit(), ioctxt);
#endif
dprintf("< err=%d\n", err);
/** Define to use stubs. Undefine to use Xen ops. */
//#define _XEN_XFR_STUB_
-extern int xen_domain_snd(Conn *xend, IOStream *io, uint32_t dom, char *vmconfig, int vmconfig_n);
+extern int xen_domain_snd(Conn *xend, IOStream *io,
+ uint32_t dom,
+ char *vmconfig, int vmconfig_n,
+ int live);
extern int xen_domain_rcv(IOStream *io, uint32_t *dom, char **vmconfig, int *vmconfig_n);
(xfr.hello <major> <minor>)
(xfr.err <code> <reason>)
- xend->xfrd (xfr.migrate <domain> <vmconfig> <host> <port>)
+ xend->xfrd (xfr.migrate <domain> <vmconfig> <host> <port> <live>)
(xfr.save <domain> <vmconfig> <file>)
xfrd->xend (xfr.suspend <domain>)
xfrd->xend (xfr.progress <percent> <rate: kb/s>)
Sxpr oxfr_configure; // (xfr.configure <vmid> <vmconfig>)
Sxpr oxfr_err; // (xfr.err <code>)
Sxpr oxfr_hello; // (xfr.hello <major> <minor>)
-Sxpr oxfr_migrate; // (xfr.migrate <vmid> <vmconfig> <host> <port>)
+Sxpr oxfr_migrate; // (xfr.migrate <vmid> <vmconfig> <host> <port> <live>)
Sxpr oxfr_migrate_ok;// (xfr.migrate.ok <value>)
Sxpr oxfr_progress; // (xfr.progress <percent> <rate: kb/s>)
Sxpr oxfr_save; // (xfr.save <vmid> <vmconfig> <file>)
unsigned long xfr_port;
char *xfr_host;
uint32_t vmid_new;
+ int live;
} XfrState;
/** Get the name of a transfer state.
if(err) goto exit;
dprintf(">*** Sending domain %u\n", state->vmid);
err = xen_domain_snd(xend, peer->out,
- state->vmid, state->vmconfig, state->vmconfig_n);
+ state->vmid,
+ state->vmconfig, state->vmconfig_n,
+ state->live);
dprintf(">*** Sent domain %u\n", state->vmid);
if(err) goto exit;
// Sending the domain suspends it, and there's no way back.
err = -EINVAL;
goto exit;
}
- err = xen_domain_snd(xend, io, state->vmid, state->vmconfig, state->vmconfig_n);
+ err = xen_domain_snd(xend, io,
+ state->vmid,
+ state->vmconfig, state->vmconfig_n,
+ 0);
if(err){
err = xfr_error(xend, err);
} else {
if(err) goto exit;
err = portof(sxpr_childN(sxpr, n++, ONONE), &port);
if(err) goto exit;
+ err = intof(sxpr_childN(sxpr, n++, ONONE), &state->live);
+ if(err) goto exit;
err = xfr_send(args, state, conn, addr, port);
} else if(sxpr_elementp(sxpr, oxfr_save)){